#include "sub.h"
#include <iostream>
#include <sstream>
#include <string>

/* Subtract the `struct timeval' values X and Y,
   storing the result in RESULT.
   Return 1 if the difference is negative, otherwise 0.  */

int timeval_subtract (timeval *result, timeval *x, timeval *y)
{
  /* Perform the carry for the later subtraction by updating y. */
  if (x->tv_usec < y->tv_usec) {
         int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
         y->tv_usec -= 1000000 * nsec;
         y->tv_sec += nsec;
  }
  if (x->tv_usec - y->tv_usec > 1000000) {
    int nsec = (x->tv_usec - y->tv_usec) / 1000000;
    y->tv_usec += 1000000 * nsec;
    y->tv_sec -= nsec;
  }
  
  /* Compute the time remaining to wait.
     tv_usec is certainly positive. */
  result->tv_sec = x->tv_sec - y->tv_sec;
  result->tv_usec = x->tv_usec - y->tv_usec;
  
  /* Return 1 if result is negative. */
  return x->tv_sec < y->tv_sec;
}



mytime::~mytime() {

}

istream& operator>> ( istream& theStream, mytime& t ) {
  int hh,mm, ss;
  string stime,ssss;

  theStream >> stime;
  
  istringstream iss(stime, istringstream::in);
  iss >> hh; iss.get(); 
  iss >> mm; iss.get(); 
  iss >> ss; iss.get( t.sep);

  iss >> ssss;
  ssss += "000";

  t.time.tv_usec = atoi(ssss.c_str());
  t.time.tv_sec = hh*60*60 + mm *60 + ss -60*60;
  
  return theStream;  
}

mytime & mytime::operator +=(double i) {
  timeval r,y;
  int ii = i;
  ostringstream jj(istringstream::out);  
  jj.fill ('0');
  jj.width (3);
  jj << (i-ii)*1000 << endl;

  y.tv_sec = -i;
  y.tv_usec = -atof(jj.str().c_str())*1000;
  
  timeval_subtract (&r, &time, &y);
    
  time.tv_sec = r.tv_sec;
  time.tv_usec = r.tv_usec;
}

ostream& operator<< ( ostream& theStream, mytime& t ) {

  char buffer[80];
  struct tm * timeinfo;
  timeinfo = localtime ( &t.time.tv_sec );
  strftime (buffer,80,"%H:%M:%S",timeinfo);

  ostringstream oss(istringstream::out);  
  oss.fill ('0');
  oss.width (3);
  oss << (t.time.tv_usec/1000);
  cout << buffer << t.sep << oss.str();

  return theStream;
}


sub_entry::sub_entry(istream & in){

  int i;
  string arrow;

  in >> n >> from >> arrow >> to;

  string line;

  getline(in,line);
  while (!in.eof()) {    
    getline(in,line);
    if (line.length() <= 1)       
      break;
    else {
      lines.push_back( line );
    }
  } 
  
}

sub_entry::~sub_entry(){
}

ostream& operator<< ( ostream& theStream, sub_entry& entry ) {
  
  if (entry.n > 0) {

    theStream << entry.n << endl;
    theStream << entry.from << " --> "  << entry.to << endl;
    
    for (vector<string>::iterator iter = entry.lines.begin(); iter != entry.lines.end(); iter ++) {
      theStream << (*iter) << endl;
    }
    
    theStream << endl;
  }
  
  return (theStream);
}

sub_entry & sub_entry::operator +=(double i){
  from += i;
  to += i;
}

ostream& operator<< ( ostream& theStream, subtitle& sub ) {
  for (vector<sub_entry*>::iterator iter = sub.entries.begin(); iter != sub.entries.end(); iter ++) {
    theStream << (**iter);
  }
  return (theStream);
}

istream &operator>> (istream& theStream, subtitle& sub) {
  sub.create_data(theStream);
}

subtitle::subtitle():filename("") { 
}

subtitle::subtitle(const string & filename):filename(filename) { 
  
  ifstream entrada(filename.c_str(), ios::in | ios::binary);
  if (!entrada) {
     cerr << "Error opening the file " + filename << endl;
   }

  if (entrada.is_open()) {    
    create_data(entrada);
  }

  entrada.close();
}

void subtitle::create_data(istream & theStream) {

  while (!theStream.eof()) {    
    sub_entry * entry = new sub_entry(theStream);
    entries.push_back(entry);
  }

}

subtitle::~subtitle() {
  for (vector<sub_entry*>::iterator iter = entries.begin(); iter != entries.end(); iter ++) {
    delete (*iter);
  }
  entries.clear();
}


subtitle & subtitle::operator +=(double i){
  
  for (vector<sub_entry*>::iterator iter = entries.begin(); iter != entries.end(); iter ++) {
    (**iter)+=i;
  }  
  
}


